const crypto = require('crypto');
const axios = require('axios');
const logger = require('./logger');
const Order = require('../models/Order');
const User = require('../models/User');
const Caregiver = require('../models/Caregiver');

/**
 * 支付服务类
 * 支持支付宝和微信支付
 */
class PaymentService {
  constructor() {
    // 支付宝配置
    this.alipayConfig = {
      appId: process.env.ALIPAY_APP_ID,
      privateKey: process.env.ALIPAY_PRIVATE_KEY,
      publicKey: process.env.ALIPAY_PUBLIC_KEY,
      gatewayUrl: process.env.ALIPAY_GATEWAY_URL || 'https://openapi.alipay.com/gateway.do',
      notifyUrl: process.env.ALIPAY_NOTIFY_URL,
      returnUrl: process.env.ALIPAY_RETURN_URL
    };

    // 微信支付配置
    this.wechatConfig = {
      appId: process.env.WECHAT_APP_ID,
      mchId: process.env.WECHAT_MCH_ID,
      apiKey: process.env.WECHAT_API_KEY,
      certPath: process.env.WECHAT_CERT_PATH,
      keyPath: process.env.WECHAT_KEY_PATH,
      notifyUrl: process.env.WECHAT_NOTIFY_URL
    };
  }

  /**
   * 创建支付订单
   * @param {Object} orderData - 订单数据
   * @param {string} paymentMethod - 支付方式 ('alipay' | 'wechat')
   * @returns {Object} 支付参数
   */
  async createPayment(orderData, paymentMethod) {
    try {
      const { orderId, amount, subject, userId } = orderData;

      // 验证订单
      const order = await Order.findById(orderId);
      if (!order) {
        throw new Error('订单不存在');
      }

      if (order.status !== 'pending') {
        throw new Error('订单状态不允许支付');
      }

      if (order.user.toString() !== userId) {
        throw new Error('无权限支付此订单');
      }

      // 生成支付流水号
      const paymentId = this.generatePaymentId();

      let paymentParams;
      if (paymentMethod === 'alipay') {
        paymentParams = await this.createAlipayOrder({
          orderId,
          paymentId,
          amount,
          subject
        });
      } else if (paymentMethod === 'wechat') {
        paymentParams = await this.createWechatOrder({
          orderId,
          paymentId,
          amount,
          subject,
          userId
        });
      } else {
        throw new Error('不支持的支付方式');
      }

      // 更新订单支付信息
      await Order.findByIdAndUpdate(orderId, {
        paymentId,
        paymentMethod,
        paymentStatus: 'pending'
      });

      logger.info(`创建支付订单成功: ${orderId}, 支付方式: ${paymentMethod}`);
      return paymentParams;
    } catch (error) {
      logger.error('创建支付订单失败:', error);
      throw error;
    }
  }

  /**
   * 创建支付宝订单
   * @param {Object} data - 订单数据
   * @returns {Object} 支付宝支付参数
   */
  async createAlipayOrder(data) {
    const { orderId, paymentId, amount, subject } = data;

    const bizContent = {
      out_trade_no: paymentId,
      total_amount: amount.toFixed(2),
      subject: subject,
      product_code: 'QUICK_WAP_WAY',
      passback_params: orderId
    };

    const params = {
      app_id: this.alipayConfig.appId,
      method: 'alipay.trade.wap.pay',
      charset: 'utf-8',
      sign_type: 'RSA2',
      timestamp: new Date().toISOString().replace('T', ' ').substring(0, 19),
      version: '1.0',
      notify_url: this.alipayConfig.notifyUrl,
      return_url: this.alipayConfig.returnUrl,
      biz_content: JSON.stringify(bizContent)
    };

    // 生成签名
    const sign = this.generateAlipaySign(params);
    params.sign = sign;

    // 构建支付URL
    const paymentUrl = this.buildAlipayUrl(params);

    return {
      paymentId,
      paymentUrl,
      method: 'GET'
    };
  }

  /**
   * 创建微信支付订单
   * @param {Object} data - 订单数据
   * @returns {Object} 微信支付参数
   */
  async createWechatOrder(data) {
    const { orderId, paymentId, amount, subject, userId } = data;

    // 获取用户openid（这里假设已存储在用户表中）
    const user = await User.findById(userId);
    if (!user || !user.wechatOpenId) {
      throw new Error('用户未绑定微信');
    }

    const params = {
      appid: this.wechatConfig.appId,
      mch_id: this.wechatConfig.mchId,
      nonce_str: this.generateNonceStr(),
      body: subject,
      out_trade_no: paymentId,
      total_fee: Math.round(amount * 100), // 微信支付金额单位为分
      spbill_create_ip: '127.0.0.1',
      notify_url: this.wechatConfig.notifyUrl,
      trade_type: 'JSAPI',
      openid: user.wechatOpenId,
      attach: orderId
    };

    // 生成签名
    params.sign = this.generateWechatSign(params);

    // 调用微信统一下单接口
    const xmlData = this.buildWechatXml(params);
    const response = await axios.post('https://api.mch.weixin.qq.com/pay/unifiedorder', xmlData, {
      headers: { 'Content-Type': 'application/xml' }
    });

    const result = this.parseWechatXml(response.data);
    
    if (result.return_code !== 'SUCCESS' || result.result_code !== 'SUCCESS') {
      throw new Error(`微信支付下单失败: ${result.err_code_des || result.return_msg}`);
    }

    // 生成前端调用参数
    const jsapiParams = {
      appId: this.wechatConfig.appId,
      timeStamp: Math.floor(Date.now() / 1000).toString(),
      nonceStr: this.generateNonceStr(),
      package: `prepay_id=${result.prepay_id}`,
      signType: 'MD5'
    };
    jsapiParams.paySign = this.generateWechatSign(jsapiParams);

    return {
      paymentId,
      jsapiParams,
      method: 'JSAPI'
    };
  }

  /**
   * 处理支付宝支付回调
   * @param {Object} params - 回调参数
   * @returns {boolean} 验证结果
   */
  async handleAlipayNotify(params) {
    try {
      // 验证签名
      if (!this.verifyAlipaySign(params)) {
        logger.error('支付宝回调签名验证失败');
        return false;
      }

      const { out_trade_no, trade_status, total_amount, gmt_payment, buyer_id } = params;
      
      // 查找订单
      const order = await Order.findOne({ paymentId: out_trade_no });
      if (!order) {
        logger.error(`支付宝回调: 订单不存在 ${out_trade_no}`);
        return false;
      }

      // 验证金额
      if (parseFloat(total_amount) !== order.totalAmount) {
        logger.error(`支付宝回调: 金额不匹配 ${out_trade_no}`);
        return false;
      }

      // 处理支付状态
      if (trade_status === 'TRADE_SUCCESS' || trade_status === 'TRADE_FINISHED') {
        await this.handlePaymentSuccess(order._id, {
          paymentMethod: 'alipay',
          transactionId: params.trade_no,
          paidAt: new Date(gmt_payment),
          payerInfo: { buyerId: buyer_id }
        });
      }

      return true;
    } catch (error) {
      logger.error('处理支付宝回调失败:', error);
      return false;
    }
  }

  /**
   * 处理微信支付回调
   * @param {string} xmlData - 回调XML数据
   * @returns {boolean} 验证结果
   */
  async handleWechatNotify(xmlData) {
    try {
      const params = this.parseWechatXml(xmlData);

      // 验证签名
      if (!this.verifyWechatSign(params)) {
        logger.error('微信支付回调签名验证失败');
        return false;
      }

      if (params.return_code !== 'SUCCESS' || params.result_code !== 'SUCCESS') {
        logger.error(`微信支付回调失败: ${params.err_code_des || params.return_msg}`);
        return false;
      }

      const { out_trade_no, total_fee, time_end, openid, attach } = params;
      
      // 查找订单
      const order = await Order.findOne({ paymentId: out_trade_no });
      if (!order) {
        logger.error(`微信支付回调: 订单不存在 ${out_trade_no}`);
        return false;
      }

      // 验证金额
      if (parseInt(total_fee) !== Math.round(order.totalAmount * 100)) {
        logger.error(`微信支付回调: 金额不匹配 ${out_trade_no}`);
        return false;
      }

      // 处理支付成功
      await this.handlePaymentSuccess(order._id, {
        paymentMethod: 'wechat',
        transactionId: params.transaction_id,
        paidAt: this.parseWechatTime(time_end),
        payerInfo: { openid }
      });

      return true;
    } catch (error) {
      logger.error('处理微信支付回调失败:', error);
      return false;
    }
  }

  /**
   * 处理支付成功
   * @param {string} orderId - 订单ID
   * @param {Object} paymentInfo - 支付信息
   */
  async handlePaymentSuccess(orderId, paymentInfo) {
    try {
      const order = await Order.findById(orderId);
      if (!order) {
        throw new Error('订单不存在');
      }

      if (order.paymentStatus === 'paid') {
        logger.info(`订单已支付，跳过处理: ${orderId}`);
        return;
      }

      // 更新订单状态
      await Order.findByIdAndUpdate(orderId, {
        paymentStatus: 'paid',
        status: 'confirmed',
        paidAt: paymentInfo.paidAt,
        transactionId: paymentInfo.transactionId,
        payerInfo: paymentInfo.payerInfo
      });

      // 更新护理员收入统计
      if (order.caregiver) {
        await Caregiver.findByIdAndUpdate(order.caregiver, {
          $inc: {
            'stats.totalEarnings': order.totalAmount,
            'stats.completedOrders': 1
          }
        });
      }

      logger.info(`订单支付成功: ${orderId}, 支付方式: ${paymentInfo.paymentMethod}`);
      
      // 这里可以添加其他业务逻辑，如发送通知等
      // await this.sendPaymentSuccessNotification(order);
    } catch (error) {
      logger.error('处理支付成功失败:', error);
      throw error;
    }
  }

  /**
   * 查询支付状态
   * @param {string} paymentId - 支付ID
   * @param {string} paymentMethod - 支付方式
   * @returns {Object} 支付状态信息
   */
  async queryPaymentStatus(paymentId, paymentMethod) {
    try {
      if (paymentMethod === 'alipay') {
        return await this.queryAlipayStatus(paymentId);
      } else if (paymentMethod === 'wechat') {
        return await this.queryWechatStatus(paymentId);
      } else {
        throw new Error('不支持的支付方式');
      }
    } catch (error) {
      logger.error('查询支付状态失败:', error);
      throw error;
    }
  }

  /**
   * 申请退款
   * @param {string} orderId - 订单ID
   * @param {number} refundAmount - 退款金额
   * @param {string} reason - 退款原因
   * @returns {Object} 退款结果
   */
  async requestRefund(orderId, refundAmount, reason) {
    try {
      const order = await Order.findById(orderId);
      if (!order) {
        throw new Error('订单不存在');
      }

      if (order.paymentStatus !== 'paid') {
        throw new Error('订单未支付，无法退款');
      }

      if (refundAmount > order.totalAmount) {
        throw new Error('退款金额不能超过订单金额');
      }

      const refundId = this.generateRefundId();
      let refundResult;

      if (order.paymentMethod === 'alipay') {
        refundResult = await this.processAlipayRefund({
          orderId,
          paymentId: order.paymentId,
          refundId,
          refundAmount,
          reason
        });
      } else if (order.paymentMethod === 'wechat') {
        refundResult = await this.processWechatRefund({
          orderId,
          paymentId: order.paymentId,
          transactionId: order.transactionId,
          refundId,
          refundAmount,
          totalAmount: order.totalAmount,
          reason
        });
      } else {
        throw new Error('不支持的支付方式');
      }

      // 更新订单退款信息
      await Order.findByIdAndUpdate(orderId, {
        refundStatus: 'processing',
        refundId,
        refundAmount,
        refundReason: reason,
        refundRequestedAt: new Date()
      });

      logger.info(`申请退款成功: ${orderId}, 退款金额: ${refundAmount}`);
      return refundResult;
    } catch (error) {
      logger.error('申请退款失败:', error);
      throw error;
    }
  }

  // 工具方法

  /**
   * 生成支付ID
   */
  generatePaymentId() {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    return `PAY${timestamp}${random}`.toUpperCase();
  }

  /**
   * 生成退款ID
   */
  generateRefundId() {
    const timestamp = Date.now();
    const random = Math.random().toString(36).substring(2, 8);
    return `REF${timestamp}${random}`.toUpperCase();
  }

  /**
   * 生成随机字符串
   */
  generateNonceStr() {
    return Math.random().toString(36).substring(2, 15) + Math.random().toString(36).substring(2, 15);
  }

  /**
   * 生成支付宝签名
   */
  generateAlipaySign(params) {
    const sortedParams = Object.keys(params)
      .filter(key => key !== 'sign' && params[key] !== '')
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&');

    const sign = crypto.createSign('RSA-SHA256');
    sign.update(sortedParams, 'utf8');
    return sign.sign(this.alipayConfig.privateKey, 'base64');
  }

  /**
   * 验证支付宝签名
   */
  verifyAlipaySign(params) {
    const sign = params.sign;
    delete params.sign;
    delete params.sign_type;

    const sortedParams = Object.keys(params)
      .filter(key => params[key] !== '')
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&');

    const verify = crypto.createVerify('RSA-SHA256');
    verify.update(sortedParams, 'utf8');
    return verify.verify(this.alipayConfig.publicKey, sign, 'base64');
  }

  /**
   * 构建支付宝支付URL
   */
  buildAlipayUrl(params) {
    const queryString = Object.keys(params)
      .map(key => `${key}=${encodeURIComponent(params[key])}`)
      .join('&');
    return `${this.alipayConfig.gatewayUrl}?${queryString}`;
  }

  /**
   * 生成微信签名
   */
  generateWechatSign(params) {
    const sortedParams = Object.keys(params)
      .filter(key => key !== 'sign' && params[key] !== '')
      .sort()
      .map(key => `${key}=${params[key]}`)
      .join('&');

    const stringSignTemp = `${sortedParams}&key=${this.wechatConfig.apiKey}`;
    return crypto.createHash('md5').update(stringSignTemp, 'utf8').digest('hex').toUpperCase();
  }

  /**
   * 验证微信签名
   */
  verifyWechatSign(params) {
    const sign = params.sign;
    delete params.sign;
    return this.generateWechatSign(params) === sign;
  }

  /**
   * 构建微信XML
   */
  buildWechatXml(params) {
    let xml = '<xml>';
    Object.keys(params).forEach(key => {
      xml += `<${key}><![CDATA[${params[key]}]]></${key}>`;
    });
    xml += '</xml>';
    return xml;
  }

  /**
   * 解析微信XML
   */
  parseWechatXml(xml) {
    const result = {};
    const regex = /<(\w+)><!\[CDATA\[([^\]]+)\]\]><\/\1>/g;
    let match;
    while ((match = regex.exec(xml)) !== null) {
      result[match[1]] = match[2];
    }
    return result;
  }

  /**
   * 解析微信时间格式
   */
  parseWechatTime(timeStr) {
    // 微信时间格式: 20220101120000
    const year = timeStr.substring(0, 4);
    const month = timeStr.substring(4, 6);
    const day = timeStr.substring(6, 8);
    const hour = timeStr.substring(8, 10);
    const minute = timeStr.substring(10, 12);
    const second = timeStr.substring(12, 14);
    return new Date(`${year}-${month}-${day} ${hour}:${minute}:${second}`);
  }

  // 这里可以添加更多支付相关的方法，如查询支付状态、处理退款等
  // 由于篇幅限制，这些方法的具体实现可以根据实际需求添加
}

module.exports = new PaymentService();